<?php

namespace App\Task;

use App\Model\Applet;
use App\Model\AppletPlayletRel;
use App\Model\DataPaymentRefund;
use App\Model\Payment;
use App\Model\Playlet;
use App\Model\PlayletEpisodes;
use App\Model\SystemOrderRefund;
use GuzzleHttp\Client;
use Hyperf\Crontab\Annotation\Crontab;
use Hyperf\DbConnection\Db;
use Hyperf\Logger\LoggerFactory;
use Hyperf\Utils\ApplicationContext;
use Psr\Log\LoggerInterface;

class WxRefundOrderTask
{
    protected LoggerInterface $logger;

    public static $getTokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
    public function __construct(protected LoggerFactory $loggerFactory)
    {
        $this->logger = $this->loggerFactory->get('log', 'wxRefundOrder');
    }
    public function execute()
    {
        $this->logger->info(date('Y-m-d H:i:s') . '------------------------开始获取审核通过的短剧');
        //获取需要获取任务的视频

        try {
            $reFundsData = DataPaymentRefund::query()->select(['id','payment_id','payment_applet_id','payment_user_id','order_id'])->where(['status' => 2,'type' => 1])->get();
            if($reFundsData->isNotEmpty()){
                    foreach ($reFundsData as $reFundsDatum){
                        //查询小程序的ID 获取appID 和密钥
                        $this->logger->info('查询小程序的ID 获取appID 和密钥');
                        $appletInfo = Applet::query()->where('id',$reFundsDatum->payment_applet_id)
                            ->where(['type' => 1])->select(['id','name','app_id','app_secret','AppKey'])->first();

                        if(!empty($appletInfo)) {

                            $this->logger->info('获取此退款订单的的小程序token:'.$appletInfo->name);
                            $accessToken = $this->getWxAccessToken($appletInfo->id,$appletInfo->app_id,$appletInfo->app_secret);
//                            $accessToken = env('WX_TEST_TOKEN');
                            if(!empty($accessToken)){

                                $userInfo = Db::table('data_user_'.$reFundsDatum->payment_applet_id)->where('id',$reFundsDatum->payment_user_id)->first();
                                $orderResult = $this->checkWxOrder($userInfo->xc_open_id, $reFundsDatum->order_id,$appletInfo->AppKey,$accessToken,1);

                                if(!empty($orderResult)){
                                    $orderInfo = $orderResult;
                                    $this->logger->info('订单状态为:'.$orderInfo['status']);
                                    //7订单退款失败
                                    if($orderInfo['status'] == 7){
                                        $reFundsDatum->status = 4;
                                        $reFundsDatum->save();
                                    //8用户退款成功
                                    }else if($orderInfo['status'] == 8){
                                        $reFundsDatum->status = 3;
                                        $reFundsDatum->refund_at = date('Y-m-d H:i:s',$orderInfo['update_time']);
                                        $this->updatePayment($reFundsDatum->payment_id);
                                        $reFundsDatum->save();
                                    }else if($orderInfo['status'] == 5){
                                        $this->updatePayment($reFundsDatum->payment_id);
                                        $reFundsDatum->refund_at = date('Y-m-d H:i:s',$orderInfo['update_time']);
                                        $reFundsDatum->status = 3;
                                        $reFundsDatum->save();

                                    }
                                }else{
                                    $this->logger->error('此退款单获取失败',[$reFundsDatum->id]);
                                }
                            }else{
                                $this->logger->error('小程序:'.$appletInfo->name.' 没有对应的token');
                            }
                        }else{
                            $this->logger->info('此退款订单没有对应的小程序',[$reFundsDatum->id]);
                        }
                    }

            }else{
                $this->logger->info('没有需要查询的退款订单');
            }
        }catch (\Exception $e){
            $this->logger->error('请求退款订单|错误：' . $e->getLine() . '|' . $e->getMessage());
        }

        $this->logger->info(date('Y-m-d H:i:s') . '------------------------结束定时退款订单');
    }

    public function updatePayment($payment_id){


        $paymentInfo = Payment::query()->select(['id','pay_time'])->where(['id' => $payment_id,'status' => 2])->first();
        if(!empty($paymentInfo)){
            $paymentInfo->status = 4;
            $paymentInfo->save();
            //插入
            SystemOrderRefund::create([
                'payment_id' => $paymentInfo->id,
                'date' => date('Y-m-d',strtotime($paymentInfo->pay_time)),
                'status' => 1,
            ]);
        }
    }


    public function getWxAccessToken($applet_id,$app_id,$app_secret){

        $container = ApplicationContext::getContainer();

        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('wx');

        $key = 'wx_access_token';
        $key .= $applet_id;
        $accessToken = $redis->get($key);
        if(empty($accessToken)){
            $params         = [
                'grant_type' => 'client_credential',
                'appid'    => $app_id,
                'secret'   => $app_secret
            ];
            //获取token
            $accessTokenInfo     = $this->request($params, self::$getTokenUrl,'GET');

            if (!empty($accessTokenInfo['access_token'])){
                $accessToken = $accessTokenInfo['access_token'];
                $redis->setex($key,7100,$accessToken);
            }else{
                $accessToken = "";
            }
        }
        $this->logger->info('微信token为：'.$accessToken);
        return $accessToken;
    }
    /**
     * 检查微信订单
     */
    public function checkWxOrder($xc_open_id,$order_id,$appkey,$accessToken,$pay_type=1){

        if($pay_type == 1) {

            $url = '/xpay/query_order';
            $params = [
                'openid' => $xc_open_id,
                'env' => 0,
                'order_id' => $order_id
            ];
            $pay_sig = $this->get_paySig($appkey, $url, $params);
            $orderUrl = 'https://api.weixin.qq.com' . $url . '?access_token=' . $accessToken . '&pay_sig=' . $pay_sig;
            $orderResult = $this->request($params, $orderUrl, 'POST');
            if($orderResult['errcode'] == 0){
                $this->logger->info('调用订单查询接口成功 返回数据：'.PHP_EOL.var_export(['result' => $orderResult], true));
                return $orderResult['order'];

            }else{
                $this->logger->error('调用媒资接口失败 返回数据：'.PHP_EOL.var_export(['result' => $orderResult], true));
            }
            return false;
        }

    }
    /**
     * 生成虚拟支付的pay_sig
     */
    public function get_paySig($appkey,$url,$signData) {
        $paySig = $this->calcPaySig($url, $signData, $appkey);
        return $paySig;
    }
    /**
     * 生成虚拟支付的pay_sig
     */
    private function calcPaySig($uri, $postBody, $appkey)
    {
        $needSignMsg = $uri . '&' . json_encode($postBody);
        $paySig = hash_hmac('sha256', $needSignMsg, $appkey);
        return $paySig;
    }
    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       =['Content-Type' => 'application/json;charset=utf-8', 'Accept' => 'application/json','Accept-Charset' => 'utf-8'];
        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;
        }
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }
}